import axios from 'axios'
import qs from 'qs'
import { clearCookies, getJustLoginUrl } from './util'
import xeUtils from 'xe-utils'
const addErrorLog = errorInfo => {
  // TODO 对错误日志进行收集
}
// 测试用
// let encryption = false
// let encryption = localStorage.getItem('ukeyEncryption') // 是否加密 TODO：获取是否加密
class HttpRequest {
  constructor (baseUrl, _fun, _errorfun) {
    this.baseUrl = baseUrl
    this.queue = {}
    this._fun = _fun
    this._errorfun = _errorfun
  }

  getInsideConfig (options) {
    // 当前url和url白名单的关系，不在白名单内需要加密。
    let currentUrl = window.location.protocol + '//' + window.location.host // 必然不存在结尾的 /
    let caDomain = localStorage.getItem('caDomain')
    let caDomainArray = []
    if (caDomain) {
      caDomainArray = caDomain.split(',')
    }
    let encryptDomain = false // 当前变量为true代表开启加密
    caDomainArray.forEach(e => {
      // 去掉最后一位的/
      e = e.endsWith('/') ? e.slice(0, -1) : e
      if (currentUrl.indexOf(e) > -1) {
        encryptDomain = true
      }
    })
    let notWhiteUrl = false
    let whiteList = localStorage.getItem('whiteInterfaceList')
    if (whiteList) {
      try {
        let temp = JSON.parse(whiteList)
        // 兼容前面的 /
        whiteList = temp.map(item => {
          return item.url.startsWith('/') ? item.url : '/' + item.url
        })
      } catch (error) {
        console.log('=====whiteList======')
        console.log(error)
        console.log('=====whiteList======')
      }
    } else {
      whiteList = []
    }
    if (options && options.url && whiteList.indexOf(options.url) === -1) {
      notWhiteUrl = true
    }
    // 把白名单结果放到options中
    options.notWhiteUrl = notWhiteUrl
    options.encryptDomain = encryptDomain
    const config = {
      baseURL: this.baseUrl,
      headers: {
        // 'Content-Type': 'application/json; charset=utf-8'
        'Content-Type':
            localStorage.getItem('ukeyEncryption') === 'true' && notWhiteUrl && encryptDomain ? 'text/plain' : 'application/json; charset=utf-8'
      }
    }
    return config
  }

  destroy (url) {
    delete this.queue[url]
    if (!Object.keys(this.queue).length) {
      // TODO页面取消正在加载的特效
    }
  }

  interceptors (instance, options) {
    // 请求拦截
    instance.interceptors.request.use(
      config => {
        // 添加全局的loading...
        if (!Object.keys(this.queue).length) {
          // TODO根据不同框架添加不同的加载特效
        }
        this.queue[options.url] = true

        // 解决路由模式下路径问题 tongbw
        let pathName = window.location.pathname
        if (pathName.indexOf('/scpcw/') > 0 && config.url.startsWith('/api/')) {
          config.url = pathName.substring(0, pathName.indexOf('/scpcw/')) + config.url
        }
        // 开启加密
        if (
          localStorage.getItem('ukeyEncryption') === 'true' &&
              localStorage.getItem('ukeyCert') !== '' &&
              config.url !== '/api/ac/sc/loginService/loginConfig' &&
              options.notWhiteUrl &&
              options.encryptDomain
        ) {
          console.log('=====请求参数======')
          console.log(options.url)
          console.log(config.data)
          console.log('=====请求参数======')

          config.data = window.app.$SOF_Encrypt(JSON.stringify(config.data))
          config.headers.cert =
                localStorage.getItem('ukeyEncryption') === 'true' ? localStorage.getItem('ukeyCert') : ''
        }
        console.log('+++++config12+++++')
        console.log(config)
        console.log('+++++config12+++++')
        return config
      },
      error => {
        return Promise.reject(error)
      }
    )
    // 响应拦截
    instance.interceptors.response.use(
      res => {
        this.destroy(options.url)
        const { data, status } = res
        if (options.php !== true) {
          options.php = false
        }
        if (data.errcode === 1001) {
          // 根据不同的返回结果进行全局拦截
          let authJustUrl = getJustLoginUrl()
          if (authJustUrl) {
            location.href = authJustUrl + xeUtils.locat().hashKey
          } else {
            clearCookies()
          }
        }
        if (typeof this._fun === 'function') {
          this._fun(data)
        }
        // 开启加密 获取登录配置不加密
        if (
          localStorage.getItem('ukeyEncryption') === 'true' &&
              options.url !== '/api/ac/sc/loginService/loginConfig' &&
              localStorage.getItem('ukeyCert') !== '' &&
              options.notWhiteUrl &&
              options.encryptDomain
        ) {
          let temp = window.app.$SOF_Decrypt(data)
          if (temp === '') {
            // 解不出来认为不需要解密
            console.log('=====解密失败======')
            console.log(options.url)
            console.log(data)
            console.log(status)
            console.log('=====解密失败======')
            return { data, status }
          }
          let temp1 = {}
          try {
            // 把解密出来的字符串转json
            temp1 = JSON.parse(temp)
            console.log('=====解密成功======')
            console.log(options.url)
            console.log(data)
            console.log(temp)
            console.log(temp1)
            console.log(typeof temp1)
            console.log(status)
            console.log('=====解密成功======')
          } catch (error) {
            console.log('=====json转换失败======')
            console.log(error)
            console.log(options.url)
            console.log('=====原数据======')
            console.log(data)
            console.log('=====原数据======')
            console.log('=====解密后数据======')
            console.log(window.app.$SOF_Decrypt(data))
            console.log('=====解密后数据======')
            console.log('=====json转换失败======')
          }
          return { data: temp1, status }
        } else {
          return { data, status }
        }
      },
      error => {
        if (typeof this._errorfun === 'function') {
          this._errorfun(error)
        }
        this.destroy(options.url)
        let errorInfo = error.response
        if (!errorInfo) {
          const {
            request: { statusText, status },
            config
          } = JSON.parse(JSON.stringify(error))
          errorInfo = {
            statusText,
            status,
            request: { responseURL: config.url }
          }
        }
        addErrorLog(errorInfo)
        return Promise.reject(error)
      }
    )
  }

  request (options) {
    const instance = axios.create()
    if (options.type === 'get') {
      options.method = 'get'
      options.params = options.data
    } else {
      if (options.type === 'put' || options.type === 'delete') {
        options.method = options.type
      } else {
        options.method = 'post'
      }
    }
    delete options.type
    if (options.php === true) {
      options.headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
      options.data = qs.stringify(options.data)
    }
    if (options.upFile === true) {
      options.headers = { 'Content-Type': 'multipart/form-data;' }
      options.withCredentials = true
    }
    options = Object.assign(this.getInsideConfig(options), options)

    this.interceptors(instance, options)
    if (options.await === true) {
      return new Promise((resolve, reject) => {
        instance(options)
          .then(response => {
            resolve(response)
          })
          .catch(error => {
            reject(error)
          })
      })
    } else {
      return instance(options)
    }
  }
}

export default HttpRequest
